/*************************************************************************
	> File Name: dasserver.cpp
	> Author: xuwenlong
	> Mail: myxuan475@126.com 
	> Created Time: 2018年09月17日 星期一 14时00分18秒
 ************************************************************************/

#include <iostream>
#include <sys/select.h>
#include <sys/socket.h>
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
#include <stdio.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string>
#include <string.h>
#include <event.h>
#include <stdlib.h>
#include <event2/rpc.h>
#include <event2/listener.h>
#include <event2/thread.h>

#include "dasserver.h"
#include <utils/logger.h>
#include <sstream>

DasServer::DasServer(Exchange *ex):
    Server(),
    m_pEx(ex),
    m_lock(true)
{
}

DasServer::~DasServer()
{
}

tUser DasServer::CreateUser()
{
    return new Client(this);
}

void DasServer::ClearUsers()
{
    {
        AutoLock autolock(m_lock);
        m_listunknown.clear();
    }while(0);

    {
        AutoLock autolock(m_lock);
        m_listcompany.clear();
    }while(0);
}

void DasServer::AddUser(tUser user)
{
    AutoLock autolock(m_lock);
    m_listunknown.push_back(user);
}

void DasServer::TimeOutEvent(int fd, short ev)
{
    AutoLock lock(m_lock);
    for (map<string,map<string,tUser> >::iterator iter = m_listcompany.begin();
         iter != m_listcompany.end();iter++) {

        map<string,tUser> &list = iter->second;
        for (map<string,tUser>::iterator it = list.begin();
             it != list.end();) {
            tUser user = it->second;

            if (user->IsTaskExit()) {
                it = list.erase(it);
            }
            else {
                it++;
            }
        }
    }

//    AutoLock autolock(m_unknownlock);
    for (vector<tUser>::iterator iter = m_listunknown.begin();iter != m_listunknown.end();
         ) {
        tUser user = *iter;
        Client *client = (Client*)user.get();
        client->IsRegister();

        if (user->IsTaskExit()) {
            iter = m_listunknown.erase(iter);
        }
        else if (client->CheckCount() >= 15) {
            iter = m_listunknown.erase(iter);
        }
        else {
            iter++;
        }
    }
}

void DasServer::addCompany(
        const string &company,
        const string &strid, tUser tu)
{
    AutoLock lock(m_lock);
    //删除已经存在的User
    for (map<string,map<string,tUser> >::iterator iter = m_listcompany.begin();
         iter != m_listcompany.end();iter++) {

        map<string,tUser> &list = iter->second;
        if (list.find(strid) != list.end()) {
            list.erase(strid);
            break;
        }
    }

    //添加到新地方去
    if (m_listcompany.find(company) != m_listcompany.end()) {
        map<string,tUser> &list = m_listcompany[company];
        if (list.find(strid) != list.end()) {
//            tu->addReference();
            list[strid] = tu;
        }
        else {
//            tu->addReference();
            list.insert(std::pair<string,tUser>(strid,tu));
        }
    }
    else {
        map<string,tUser> list;
        list.insert(std::pair<string,tUser>(strid,tu));
//        tu->addReference();
        m_listcompany.insert(
                    std::pair<string,map<string,tUser> >(company,list));
    }

//    AutoLock autolock(m_unknownlock);
    for (vector<tUser>::iterator iter = m_listunknown.begin();iter != m_listunknown.end();
         iter++) {
        tUser user = *iter;
        if (user.get() == tu.get()) {
            m_listunknown.erase(iter);
            break;
        }
    }
}

Exchange *DasServer::Ex()
{
    return m_pEx;
}

DAS_RESULT DasServer::getAcquisitorList(
        const Json::Value &params,
        Json::Value &result) {

    AutoLock lock(m_lock);
    for (map<string,map<string,tUser> >::iterator iter = m_listcompany.begin();
         iter != m_listcompany.end();iter++) {

        Json::Value jc,jd;
        string cpy = iter->first;
        map<string,tUser> &list = iter->second;
        for (map<string,tUser>::iterator it = list.begin();
             it != list.end();it++) {
            tUser user = it->second;
            Client *client =static_cast<Client*>(user.get());
            if (!client->IsTaskExit())
                jc.append(client->JsonAcquisitor());
        }
        jd["clients"] = jc;
        jd["company"] = cpy;
        result.append(jd);
    }

//    AutoLock autolock(m_unknownlock);
    Json::Value jct,jdt;
    for (vector<tUser>::iterator iter = m_listunknown.begin();iter != m_listunknown.end();
         iter++) {
        tUser user = *iter;
        Client *client =static_cast<Client*>(user.get());
        if (!client->IsTaskExit())
            jct.append(client->JsonAcquisitor());
    }
    if (!jct.isNull()) {
        jdt["clients"] = jct;
        jdt["company"] = "##";
        result.append(jdt);
    }

    if (result.isNull())
        return DAS_NOINFO;

    return DAS_SUCCESS;
}

tUser DasServer::FindClient(const string &strId)
{
    AutoLock lock(m_lock);
    for (map<string,map<string,tUser> >::iterator iter = m_listcompany.begin();
         iter != m_listcompany.end();iter++) {

        map<string,tUser> &list = iter->second;
        if (list.find(strId) != list.end()) {
            tUser user = (tUser)list[strId];
            if (user.valid())
                return user;
            return NULL;
        }
    }
    return NULL;
//    return static_cast<Client*>(Server::FindUser(&strId).get());
}

bool DasServer::Compare(int flag,tUser user,const void *arg)
{
    if (flag == 0) {
        const std::string& strId = *((std::string*)(arg));
        Client *client =static_cast<Client*>(user.get());
        return client->IsIdEqual(strId);
    }
    else if (flag == 1) {
        const std::string& company = *((std::string*)(arg));
        Client *client =static_cast<Client*>(user.get());
        return (company == client->CompanyName());
    }
    return false;
}

string DasServer::Report(const string &mark)
{
    AutoLock lock(m_lock);
    string report;
    int ip = 0;
    for (map<string,map<string,tUser> >::iterator iter = m_listcompany.begin();
         iter != m_listcompany.end();iter++) {
        string proname = iter->first;
        map<string,tUser> gwlist = iter->second;

        stringstream pro;
        int iw = 0;
        pro << mark <<++ip<< ". **项目名称:** "<<proname<<"\n";
        pro << mark <<ip<< ".1. **上报网关总数:** "<<gwlist.size()<<"\n";
        pro << mark <<ip<< ".2. **详细报告:**\n";
        int errgt = 0;
        int errdev = 0;
        int errup = 0;
        for (map<string,tUser>::iterator giter = gwlist.begin();
             giter != gwlist.end();giter++) {
            string strid = giter->first;
            tUser tu = giter->second;
            Client *client = static_cast<Client*>(tu.get());
            pro <<"#"<<mark<<ip<<".2."<<++iw<<". **网关ID:** "<<strid<<"\n";
            pro << client->Report("- ");

        }
        report += pro.str()+"------------------------\n\n";
    }
    return report;
}
